package net.blank.ui.core
{
	import flash.display.DisplayObjectContainer;
	import flash.text.engine.ContentElement;
	import flash.text.engine.EastAsianJustifier;
	import flash.text.engine.TextBlock;
	import flash.text.engine.TextJustifier;
	import flash.text.engine.TextLine;
	import flash.text.engine.TextLineValidity;
	import flash.text.engine.TextRotation;
	
	import net.blank.pool.Pool;
	
	/**
	 * 文本创建器
	 * @author blank
	 * 
	 */
	public final class TextCreator
	{
		/**
		 * 创建文本块
		 */
		private static const TEXT_BLOCK:TextBlock=new TextBlock();
		
		/**
		 * 默认对齐方式
		 */
		public static const DEFAULT_TEXT_JUSTIFIER:EastAsianJustifier=new EastAsianJustifier("cn");
		
		/**
		 * 释放文本行
		 * @param textLines
		 * @param parent
		 * 
		 */
		public static function releaseTextLines(
			textLines:Vector.<TextLine>,
			parent:DisplayObjectContainer=null
		):void{
			var i:int=textLines.length, textLine:TextLine;
			
			while(--i>-1){
				textLine=textLines.pop();
				
				if(parent){
					parent.removeChild(textLine);
				}
				
				if (textLine.validity != TextLineValidity.INVALID 
					&& 
					textLine.validity != TextLineValidity.STATIC
				){
					textLine.validity = TextLineValidity.INVALID;
				}
				
				textLine.userData = null;
				
				Pool.storeObj(textLine);
			}
		}
		
		/**
		 * 根据垂直对齐方式,计算第一行文本的 y 坐标
		 * @param verticalAlign 垂直对齐方式
		 * @param boundsY
		 * @param boundsHeight
		 * @param textHeight
		 * @return 
		 * 
		 */
		private static function countStartY(
			verticalAlign:String,
			boundsY:Number,
			boundsHeight:Number,
			textHeight:Number
		):Number{
			switch(verticalAlign){
				default:
				case Arrange.TOP:
					return boundsY;
				case Arrange.MIDDLE:
					return boundsY + ((boundsHeight - textHeight) / 2);
				case Arrange.BOTTOM:
					return boundsY + (boundsHeight - textHeight);
			}
			return 0;
		}
		
		/**
		 * 根据水平对齐方式,计算第一行文本的 x 坐标
		 * @param verticalAlign
		 * @param bounds
		 * @param textHeight
		 * @return 
		 * 
		 */
		private static function countStartX(
			horizontalAlign:String,
			boundsX:Number,
			boundsWidth:Number,
			textWidth:Number
		):Number{
			switch(horizontalAlign){
				default:
				case Arrange.LEFT:
					return boundsX;
				case Arrange.CENTER:
					return boundsX + ((boundsWidth - textWidth) / 2);
				case Arrange.RIGHT:
					return boundsX + (boundsWidth - textWidth);
			}
			return 0;
		}
		
		/**
		 * 垂直排列文本行
		 * @param textLines
		 * @param parent
		 * @param boundsX
		 * @param boundsY
		 * @param boundsWidth
		 * @param boundsHeight
		 * @param gap
		 * @param textHeight
		 * @param align
		 * @param verticalAlign
		 * @param isCreatedAll
		 * 
		 */
		public static function verticalArrange(
			textLines:Vector.<TextLine>,
			parent:DisplayObjectContainer,
			boundsX:Number,
			boundsY:Number,
			boundsWidth:Number,
			boundsHeight:Number,
			gap:Number,
			textHeight:Number,
			align:String,
			verticalAlign:String,
			isCreatedAll:Boolean
		):void{
			//根据垂直对齐方式,计算第一行文本的 y 坐标
			const startY:Number = isCreatedAll ? countStartY(verticalAlign,boundsY,boundsHeight,textHeight) : boundsY;
			
			//添加文本行
			var y:Number=0;
			var i:int,n:int=textLines.length,textLine:TextLine;
			//为了减少判断,以提高性能.下面本可写为一个循环的写成了两个循环
			switch(align){
				default:
				case Arrange.LEFT:
					for(i=0;i<n;i++){
						textLine=textLines[i];
						
						if(i == 0){
							y = startY + textLine.totalAscent;
						}else{
							y += textLine.totalAscent + gap;
						}
						
						textLine.x=boundsX;
						textLine.y = y;
						
						y += textLine.totalDescent;
						
						parent.addChild(textLine);
					}
					break;
				case Arrange.CENTER:
					for(i=0;i<n;i++){
						textLine=textLines[i];
						
						if(i == 0){
							y = startY + textLine.totalAscent;
						}else{
							y += textLine.totalAscent + gap;
						}
						
						textLine.x=boundsX+(boundsWidth-textLine.width)/2;
						textLine.y = y;
						
						y += textLine.totalDescent;
						
						parent.addChild(textLine);
					}
					break;
				case Arrange.RIGHT:
					for(i=0;i<n;i++){
						textLine=textLines[i];
						
						if(i == 0){
							y = startY + textLine.totalAscent;
						}else{
							y += textLine.totalAscent + gap;
						}
						
						textLine.x=boundsX+boundsWidth-textLine.width;
						textLine.y = y;
						
						y += textLine.totalDescent;
						
						parent.addChild(textLine);
					}
					break;
			}
		}
		
		/**
		 * 水平排列文本行
		 * @param textLines
		 * @param parent
		 * @param boundsX
		 * @param boundsY
		 * @param boundsWidth
		 * @param boundsHeight
		 * @param gap
		 * @param textWidth
		 * @param align
		 * @param horizontalAlign
		 * @param isCreatedAll
		 * 
		 */
		public static function horizontalArrange(
			textLines:Vector.<TextLine>,
			parent:DisplayObjectContainer,
			boundsX:Number,
			boundsY:Number,
			boundsWidth:Number,
			boundsHeight:Number,
			gap:Number,
			textWidth:Number,
			align:String,
			horizontalAlign:String,
			isCreatedAll:Boolean
		):void{
			//根据垂直对齐方式,计算第一行文本的 y 坐标
			const startX:Number = isCreatedAll ? countStartX(horizontalAlign,boundsX,boundsWidth,textWidth) : boundsX;
			
			//添加文本行
			var x:Number=0;
			var i:int,n:int=textLines.length,textLine:TextLine;
			//为了减少判断,以提高性能.下面本可写为一个循环的写成了两个循环
			switch(align){
				default:
				case Arrange.TOP:
					for(i=0;i<n;i++){
						textLine=textLines[i];
						
						if(i == 0){
							x = startX + textLine.totalDescent;
						}else{
							x += textLine.totalDescent + gap;
						}
						
						textLine.x = x;
						textLine.y = boundsY;
						
						x += textLine.totalAscent;
						
						parent.addChild(textLine);
					}
					break;
				case Arrange.MIDDLE:
					for(i=0;i<n;i++){
						textLine=textLines[i];
						
						if(i == 0){
							x = startX + textLine.totalDescent;
						}else{
							x += textLine.totalDescent + gap;
						}
						
						textLine.x = x;
						textLine.y = boundsY + (boundsHeight - textLine.height) / 2;
						
						x += textLine.totalAscent;
						
						parent.addChild(textLine);
					}
					break;
				case Arrange.BOTTOM:
					for(i=0;i<n;i++){
						textLine=textLines[i];
						
						if(i == 0){
							x = startX + textLine.totalDescent;
						}else{
							x += textLine.totalDescent + gap;
						}
						
						textLine.x = x;
						textLine.y = boundsY + boundsHeight - textLine.height;
						
						x += textLine.totalAscent;
						
						parent.addChild(textLine);
					}
					break;
			}
		}
		
		/**
		 * 创建水平文本,固定行间距
		 * @param contents 文本内容
		 * @param textLines
		 * @param parent
		 * @param boundsX
		 * @param boundsY
		 * @param boundsWidth
		 * @param boundsHeight
		 * @param align
		 * @param verticalAlign
		 * @param gap
		 * @param textJustifier
		 * @return 
		 * 
		 */
		public static function createTextLines_h_fixedGap(
			contents:Vector.<ContentElement>,
			textLines:Vector.<TextLine>,
			parent:DisplayObjectContainer,
			boundsX:Number,
			boundsY:Number,
			boundsWidth:Number,
			boundsHeight:Number,
			align:String=Arrange.LEFT,
			verticalAlign:String=Arrange.TOP,
			gap:Number=4,
			textJustifier:TextJustifier=null,
			enableLink:Boolean=false
		):Boolean{
			releaseTextLines(textLines,parent);
			
			if(boundsWidth <= 0 || boundsHeight <= 0){
				return false;
			}
			
			/**是否将文本行创建完成*/
			var isCreatedAll:Boolean;
			var textHeight:Number=0;
			
			//创建文本行
			var n:int=0, i:int;
			var textLine:TextLine, recycleLine:TextLine;
			
			const LEN:int=contents.length;
			var textBlock:TextBlock=TEXT_BLOCK;
			for(i=0;i<LEN;i++){
				if(enableLink){
					textBlock=new TextBlock();
				}
				//设置文本
				textBlock.content=contents[i];
				
				textBlock.textJustifier=textJustifier || DEFAULT_TEXT_JUSTIFIER;
				
				while(true){
					recycleLine=Pool.restoreObj(TextLine);
					if(recycleLine){
						textLine=textBlock.recreateTextLine(recycleLine,textLine,boundsWidth);
					}else{
						textLine=textBlock.createTextLine(textLine,boundsWidth);
					}
					
					if(!textLine){
						isCreatedAll=true;
						break;
					}
					
					textHeight += (n == 0 ? textLine.totalAscent : textLine.totalHeight + gap);
					
					textLines[n++]=textLine;
					
					//如果这一行显示不完,则停止创建
					if(textHeight >= boundsHeight){
						break;
					}
				}
				
				textLine=null;
				textBlock.releaseLineCreationData();
			}
			
			verticalArrange(textLines,parent,boundsX,boundsY,boundsWidth,boundsHeight,gap,textHeight,align,verticalAlign,isCreatedAll);
			
			return isCreatedAll;
		}
		
		/**
		 * 创建垂直文本,固定行间距
		 * @param content
		 * @param textLines
		 * @param parent
		 * @param boundsX
		 * @param boundsY
		 * @param boundsWidth
		 * @param boundsHeight
		 * @param align
		 * @param horizontalAlign
		 * @param gap
		 * @param textJustifier
		 * @return 
		 * 
		 */
		public static function createTextLines_v_fixedGap(
			contents:Vector.<ContentElement>,
			textLines:Vector.<TextLine>,
			parent:DisplayObjectContainer,
			boundsX:Number,
			boundsY:Number,
			boundsWidth:Number,
			boundsHeight:Number,
			align:String=Arrange.TOP,
			horizontalAlign:String=Arrange.LEFT,
			gap:Number=4,
			textJustifier:TextJustifier=null,
			enableLink:Boolean=false
		):Boolean{
			releaseTextLines(textLines,parent);
			
			if(boundsWidth <= 0 || boundsHeight <= 0){
				return false;
			}
			
			/**是否将文本行创建完成*/
			var isCreatedAll:Boolean;
			var textWidth:Number=0;
			
			//创建文本行
			var n:int=0,i:int;
			var textLine:TextLine, recycleLine:TextLine;
			
			const LEN:int=contents.length;
			var textBlock:TextBlock=TEXT_BLOCK;
			for(i=0;i<LEN;i++){
				if(enableLink){
					textBlock=new TextBlock();
				}
				//设置文本
				textBlock.content=contents[i];
				
				//文本方向
				textBlock.lineRotation=TextRotation.ROTATE_90;
				textBlock.textJustifier=textJustifier || DEFAULT_TEXT_JUSTIFIER;
				while(true){
					recycleLine=Pool.restoreObj(TextLine);
					if(recycleLine){
						textLine=textBlock.recreateTextLine(recycleLine,textLine,boundsHeight);
					}else{
						textLine=textBlock.createTextLine(textLine,boundsHeight);
					}
					
					if(!textLine){
						isCreatedAll=true;
						break;
					}
					
					textWidth += (n == 0 ? textLine.totalAscent : textLine.width + gap);
					
					textLines[n++]=textLine;
					
					//如果这一行显示不完,则停止创建
					if(textWidth >= boundsWidth){
						break;
					}
				}
				
				textLine=null;
				textBlock.releaseLineCreationData();
			}
			
			horizontalArrange(textLines,parent,boundsX,boundsY,boundsWidth,boundsHeight,gap,textWidth,align,horizontalAlign,isCreatedAll);
			
			return isCreatedAll;
		}
	}
}